﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DWORD = System.UInt32;
using BOOL = System.Boolean;
using WDC_DRV_OPEN_OPTIONS = System.UInt32;
using System.Collections;
using wdc_err = Jungo.wdapi_dotnet.WD_ERROR_CODES;
using Jungo.wdapi_dotnet;

namespace PciDeviceLib
{
    public class PCI_DeviceList : ArrayList
    {


        //private string PCI_DEFAULT_LICENSE_STRING  = "12345abcde1234.license";
        private string PCI_DEFAULT_LICENSE_STRING = "6C3CC2CFE89E7AD0424A070D434A6F6DC4957767.Administrator";
        // TODO: If you have renamed the WinDriver kernel module (windrvr6.sys),
        //  change the driver name below accordingly
        private string PCI_DEFAULT_DRIVER_NAME = "windrvr6";
        public DWORD PCI_DEFAULT_VENDOR_ID = 0x000;/*y vendor */
        public DWORD PCI_DEFAULT_DEVICE_ID = 0x000; /* any device */

       // private DWORD PCI_DEFAULT_VID = 0x0;/*y vendor */
       // private DWORD PCI_DEFAULT_DID = 0x0; /* any device */


      //  private readonly int ERROR = 1;


        private static PCI_DeviceList instance;



        public static PCI_DeviceList TheDeviceList()
        {
            if (instance == null)
            {
                instance = new PCI_DeviceList();
            }
            return instance;
        }

        public PCI_DeviceList() { }

        public DWORD Init()
        {
            //设置名称，在设备打开前必须调用且仅一次，重复调用或错误返回null
            if (windrvr_decl.WD_DriverName(PCI_DEFAULT_DRIVER_NAME) == null)
            {
                return (DWORD)wdc_err.WD_SYSTEM_INTERNAL_ERROR;
            }



            DWORD dwStatus = wdc_lib_decl.WDC_DriverOpen((WDC_DRV_OPEN_OPTIONS)wdc_lib_consts.WDC_DRV_OPEN_DEFAULT, PCI_DEFAULT_LICENSE_STRING);
            if (dwStatus != (DWORD)wdc_err.WD_STATUS_SUCCESS)
            {

                return dwStatus;
            }
            return Populate_new_new();
        }


        //王国庆新增
        public PCI_Device Get(uint _VendorId, uint _DeviceId)
        {
            if (_VendorId <= 0 || _DeviceId <= 0)
                return null;
            foreach (PCI_Device item in this)
            {
                if (item.id.dwVendorId == _VendorId && item.id.dwDeviceId == _DeviceId)
                {
                    return item;
                }

            }
            return null;
        }
        public PCI_Device Get(int index)
        {
            if (index >= this.Count || index < 0)
                return null;
            return (PCI_Device)this[index];
        }
        public PCI_Device Get(WD_PCI_SLOT slot)
        {

            foreach (PCI_Device device in this)
            {
                if (device.IsMySlot(ref slot))
                    return device;
            }
            return null;
        }
        public PCI_Device Get(uint dwBus, uint dwSlot, uint dwFunction)
        {
            WD_PCI_SLOT slot;

            slot.dwBus = dwBus;
            slot.dwSlot =dwSlot;
            slot.dwFunction = dwFunction;

            if (slot.dwBus != null && slot.dwSlot != null)
            {
                foreach (PCI_Device device in this)
                {
                    if (device.IsMySlot(ref slot))
                        return device;
                }
            }
           
            return null;
        }

        private DWORD Populate_new_new()
        {
            DWORD dwStatus;
           // Boolean temp = false;
            //Boolean temp1 = false;

            //用于存放PCI扫描结果的结构
            WDC_PCI_SCAN_RESULT scanResult = new WDC_PCI_SCAN_RESULT();

            //扫描PCI总线上所有存在的设备，返回0正常，否则返回错误代码
            dwStatus = wdc_lib_decl.WDC_PciScanDevices(PCI_DEFAULT_VENDOR_ID,
                PCI_DEFAULT_DEVICE_ID, scanResult);

            if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
            {
                return dwStatus;
            }

            if (scanResult.dwNumDevices == 0)
            {
                return (DWORD)wdc_err.WD_INVALID_PARAMETER;
            }


            //王国庆新增

            Convert.ToUInt32("c514", 16);

            //按顺序将板卡信息写入数组
            PCI_Device device;

            for (int j = 0; j < scanResult.dwNumDevices; ++j)
            {
                WD_PCI_SLOT slot = scanResult.deviceSlot[j];

                device = new PCI_Device(scanResult.deviceId[j].dwVendorId,
                    scanResult.deviceId[j].dwDeviceId, slot);



                this.Add(device);

            }

            return (DWORD)wdc_err.WD_STATUS_SUCCESS;
        }

        //关闭窗体触发？
        public void Dispose()
        {

            foreach (PCI_Device device in this)
                device.Dispose();
            this.Clear();

            DWORD dwStatus = wdc_lib_decl.WDC_DriverClose();
            if (dwStatus != (DWORD)wdc_err.WD_STATUS_SUCCESS)
            {
                Exception excp = new Exception("PCI_DeviceList.Dispose: " +
                    "Failed to uninit the WDC library. Error 0x" +
                    dwStatus.ToString("X") + utils.Stat2Str(dwStatus));
                throw excp;
            }
        }
    };
}
